#include "marquee_isr.h"
#include "c8051f3xx.h"

// Variables for storing "ticks" from the timer to do refresh and scrolling
unsigned char refresh_ticks;		    // How many ticks of the timer for refresh
unsigned char scroll_ticks;			   // How many refresh_ticks have we done
unsigned char target_scroll_ticks;	// The target to aim at

//Variables for controlling the display
unsigned char row_control;				// which row is used
unsigned char charByte[8];				// array of bytes holding the currently loaded character
int index = 0;							      // index of the charByte array
unsigned int charNum = 0;				 // character in the sequence
Flash_Address fa;
unsigned char red;
unsigned char green;

void Init_Ticks(void)
{
	refresh_ticks = 0;				// Start with 0 refresh ticks
	scroll_ticks = 0;				// Start with 0 refreshes
	target_scroll_ticks = MEDIUM_TICKS;	//Start at medium scroll speed

	fa->high = 0;
	fa->medium = 0;
	fa->low = 0;
	row_control = 0b10000000;
}

// Call with a number of ticks defined in marquee_constants.h
void Set_Scroll_Ticks(unsigned char ticks)
{
	target_scroll_ticks = ticks;
}

void Tick_ISR(void) interrupt 5
{
	refresh_ticks++;		// increment the refresh counter
	if (refresh_ticks == DIVISION_FACTOR)
	{
		refresh_ticks = 0;
		refresh_func();
	
		scroll_ticks++;
		if (scroll_ticks == target_scroll_ticks)
		{
			scroll_ticks = 0;
			scroll_func();
		}
	}
}

void scroll_func()
{
  /*spi_write_byte(), P0^5 = true, wait, p0^5 = false */
  if (index == 8)                                     // if we have pushed the current character
  {
 	  charNum++;                                        // increment charNum
    if (charNum>MESSAGE_LENGTH)                       // Have we reached the end of the message?
      charNum = 0;                                    // Then begin again
      
    index = 0;                                        // reset the counter
	
    unsigned char k[2];                               // prepare a buffer for the character data

	  fa->low = 2*charNum;                              // increment the address (2bytes/character)
	  flash_read_byte(fa, k, 2);                        // read the next character from flash mem
    
    unsigned char b = 8 * k[1];                       // first is the charcter's number
    unsigned char bdata v = k[0];                     // second is its color code (store in 
                                                      // bit-addressable space)
    CY = v^1                                                      
    for (int j = 0; j<8; j++)                             // loop through red and green
      red = red << 1;                                    // filling them with the appropriate values

    CY = V^0
    for (int k = 0; j<8; j++)
      green = green << 1;
    
    for (int i = 0; i<8; i++)                         // set charByte to the font data of the char
      charByte[i] = FONT_DATA[b+i];                   // specified
  }  
  
  unsigned char redX   = charByte[index] & red;       // bit-wise AND red and green with the font 
  unsigned char greenX = charByte[index] & green;     // bytes
  
  spi_write_byte(redX);                               // send both red and green bytes through 
  spi_write_byte(greenX);                             // SPI interface to the LED controllers
  
  P0^5 = true;                                        // Latch Pin 5 of Port 0, initiating the transfer
  greenX++;                                           // Waste two cycles to let the transfer go through
  greenX--;                                           
  
  P0^5 = false;                                       // Un-latch the port to end the SPI transfer.
  
}//end scroll_func

void refresh_func()
{
  row_control = row_control << 1;                     // rotate row_control to the left
  if (row_control == 0)                               // have we looped?
	   row_control = 1;                                 // then start over
	
  unsigned char bdata x = row_control;                // create bit-addressable variable x
                                                      // set it equal to row-control
  P0^7 = x^0;                                         // assign the various ports that
  P1^0 = x^1;                                         // control the rows to the values in
  P1^1 = x^2;                                         // x (row_control)
  P1^2 = x^3;
  P1^3 = x^4;
  P1^4 = x^5;
  P1^5 = x^6;
  P1^6 = x^7;
  
}//end refresh_func